package com.ibm.member.common.util;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.apache.commons.collections.map.LRUMap;

import net.sf.cglib.beans.BeanCopier;
import net.sf.cglib.beans.BeanMap;
import net.sf.cglib.core.Converter;

@SuppressWarnings("unchecked")
public class BeanUtil {

    private static final Map<String, BeanCopier> beanCopierCache = new LRUMap(32);

    private static final DefaultConverter converter = new DefaultConverter();

    public static void copyBean(Object source, Object target) {
        String key = source.getClass().getName() + target.getClass().getName();
        BeanCopier beanCopier = beanCopierCache.get(key);

        if (beanCopier == null) {
            beanCopier = BeanCopier.create(source.getClass(), target.getClass(), false);
            synchronized (beanCopierCache) {
                beanCopierCache.put(key, beanCopier);
            }
        }
        beanCopier.copy(source, target, converter);
    }

    public static void copyBeanNotNull(Object source, Object target) {
        Map<String, Object> map = toMapNotNull(source);

        BeanMap beanMap = BeanMap.create(target);
        beanMap.putAll(map);
    }

    public static Map<String, Object> toMapNotNull(Object obj) {
        BeanMap beanMap = BeanMap.create(obj);
        Set<String> keySet = beanMap.keySet();

        Map<String, Object> result = new HashMap<String, Object>(keySet.size());
        for (String key : keySet) {
            Object value = beanMap.get(key);
            if (value != null)
                result.put(key, value);
        }
        return result;
    }
}

class DefaultConverter implements Converter {
    @SuppressWarnings("rawtypes")
    @Override
    public Object convert(Object value, Class target, Object context) {
        return value;
    }
}